Компиляция
===========

Мы видели, что есть два инструмента, которые прежде всего используются в программировании,

#. текстовый редактор
#. компилятор

Программы пишутся в текстовых редакторах. Концепция компиляции и функции компилятора также должны быть
поняты при использовании компилируемых языков, таких как D.

Машинный код
------------

.. index::
    Машинный код
    CPU

Основным элементом компьютера является микропроцессор (или CPU, сокращение от central processing unit
Указание процессору, что делать, называется кодированием, а инструкции , которые используются при этом, называются машинным кодом.
Большинство архитектур процессоров используют машинный код, специфичный для данной конкретной архитектуры процессора.
Эти инструкции машинного кода определяются в соответствии с аппаратными ограничениями на этапе проектирования архитектуры.
На самом низком уровне эти инструкции машинного кода реализуются в виде электрических сигналов. Поскольку простота
кодирования не является основной на этом уровне, написание программ непосредственно в
виде машинного кода центрального процессора является очень сложной задачей.
Эти инструкции машинного кода представляют собой специальные числа, которые представляют различные
операции, поддерживаемые центральным процессором. Например, для воображаемого 8-разрядного процессора

#. число 4 может представлять операцию загрузки
#. число 5 может представлять операцию сохранения,
#. число 6 может представлять операцию увеличения.

Предполагая, что крайние 3 бита слева - это номер операции, а крайние 5 бит справа - это значение, используемое в этой операции,
пример программы в машинном коде для этого процессора может выглядеть следующим образом:
Значение операции, означающее

.. code-block:: console

    100 11110 LOAD 11110
    101 10100 STORE 10100
    110 10100 INCREMENT 10100
    000 00000 PAUSE


Я вернусь к этой концепции позже в последующих главах. Тем не менее, я привожу пример
выше просто для того, чтобы показать, насколько сложной может быть работа с машинным кодом. Будучи настолько близкой
к аппаратному обеспечению, машинный код не подходит для представления понятий более высокого уровня, таких как игральная карта или студенческая запись.


Язык программирования
----------------------


Языки программирования разработаны как эффективные способы программирования центрального процессора,
способные представлять концепции более высокого уровня. Языкам программирования не
приходится сталкиваться с аппаратными ограничениями; их основными целями являются простота использования и
выразительность. Языки программирования проще для понимания людьми,они ближе к естественным языкам:

.. code-block:: d

    if (a_card_has_been_played())
    {
        display_the_card();
    }

Однако языки программирования придерживаются гораздо более строгих и формальных правил, чем любой разговорный язык.

Интерпретатор
--------------

..  index::
    интерпретатор

Интерпретатор - это инструмент (программа), который считывает инструкции из исходного кода
и выполняет их. Например, для приведенного выше кода интерпретатор
понял бы, что сначала нужно

#. выполнить a_card_has_been_played(),
#. а затем если условие в предыдущей строке истинно выполнить display_the_card().

С точки зрения программиста, выполнение с помощью интерпретатора включает в себя всего два шага:

#. написание исходного кода
#. передачу его интерпретатору

Интерпретатор должен читать и понимать инструкции каждый раз, когда выполняется программа. По этой причине запуск программы с помощью интерпретатора
обычно происходит медленнее, чем запуск скомпилированной версии той же программы.
Кроме того, интерпретаторы обычно выполняют очень небольшой анализ кода перед его выполнением.
В результате большинство интерпретаторов обнаруживают программные ошибки только после начала выполнения программы.
Некоторые языки, такие как Perl, Python и Ruby, были разработаны как очень
гибкие и динамичные, что усложняет анализ кода. Эти языки имеют традиционно используют с интерпретатор.

Компилятор
-------------

.. index::
    компилятор
    компиляция
    ошибка компиляции


Компилятор - это еще один инструмент, который считывает инструкции программы из исходного
кода. В отличие от интерпретатора, он не выполняет код; он создает программу, написанную на другом языке (обычно машинный код). Эта
созданная программа отвечает за выполнение инструкций, которые были написаны программистом. С точки зрения программиста, выполнение
с помощью компилятора включает в себя три этапа:

#. написание исходного кода,
#. компиляция исходного кода
#. запуск созданной программы

В отличие от интерпретатора, компилятор считывает и понимает исходный код только
один раз, во время компиляции. По этой причине и в целом скомпилированная программа
выполняется быстрее по сравнению с выполнением этой программы с помощью интерпретатора. Компиляторы
обычно выполняют расширенный анализ кода, что помогает быстро создавать
программы и выявлять программные ошибки еще до того, как программа начнет
выполняться. С другой стороны, необходимость компилировать программу каждый раз при ее
изменении является усложнением и потенциальным источником человеческих ошибок. Более того, программа
программы, созданные компилятором, обычно могут запускаться только на определенной
платформе; для запуска на другом типе процессора или в другой операционной
системе программу необходимо перекомпилировать. Кроме того, языки, которые компилируются, обычно менее динамичны, чем те, которые выполняются в
интерпретаторе.
По таким причинам, как безопасность и производительность, некоторые языки были разработаны
для компиляции. Ada, C, C++ и D - некоторые из них.

**Ошибка компиляции**

Поскольку компилятор обрабытывает программу в соответствии с правилами языка, он
останавливает компиляцию, как только обнаруживает недопустимые инструкции. Недопустимые
инструкции - это те, которые выходят за рамки спецификации языка.
Такие проблемы, как несоответствующая круглая скобка, пропущенная точка с запятой,
ключевое слово с ошибкой в написании и т.д. все они приводят к ошибкам компиляции.
Компилятор также может выдавать предупреждение, когда видит подозрительный
фрагмент кода, который может вызывать беспокойство, но не обязательно является ошибкой. Однако
предупреждения почти всегда указывают на фактическую ошибку или плохой стиль, поэтому обычной
практикой является рассмотрение большинства или всех предупреждений как ошибок. Компилятор dmd переключается в режими 
предупреждение как ошибка при помощи опции -w.
